from flask import jsonify, make_response, g, request
from flask_jwt_extended import create_access_token, get_jwt_identity
from flask_restful import Resource

from apps.model.initModel import base64Jia, base64Jie
from apps.model.serializeModel import model_to_list, model_to_dict
from apps.settingApi.api.users.getPermission import userPermission
from apps.settingApi.api.users.utils import postListOnLineModel, getListOnLineModel
from apps.settingApi.switchCase.casePrimaryKey import caseGetPrimaryKeyData
from apps.settingApi.switchCase.serializeParameter import serializeGetFilter, getArgsData, serializeParData, \
    pageResultData, getParmData
from apps.settingApi.utils import verifyDateOverdue, getDataTime, getLessees
from apps.settingApi.api.users.model import usersModel,onLineModel
from apps.settingApi.api.lessees.model import lesseesModel
from comm.sqlalchemyConfig import db
from comm.decorator import login_required
from socketIo.client import clientLoginOut

usersViewModel = usersModel
lesseesViewModel = lesseesModel
onLineViewModel = onLineModel
class loginListView(Resource):
    # 查询用户列表
    @login_required()
    def get(self):
        # 获取所有的参数
        serializeFilterList, args = serializeGetFilter(usersViewModel)
        valid = args.get("valid", '1')
        # 1查询全部、2查询未过期的3、查询过期的
        if valid in ('1', '2', '3'):
            if valid == '2':
                serializeFilterList.append(usersViewModel.end_time > getDataTime())
            if valid == '3':
                serializeFilterList.append(usersViewModel.end_time <= getDataTime())
        modelDataObj = usersViewModel.query.filter(*serializeFilterList).order_by(usersViewModel.id.desc()).paginate(page=args['page'],
                                                                                    per_page=args['pageSize'],
                                                                                    error_out=False)
        objData = pageResultData(modelDataObj)
        result = model_to_list(modelDataObj, [])
        objData["data"] = result  # 分页数据
        return make_response(jsonify({'msg': '成功', 'result': objData}), 200)

    # 新增用户
    @login_required()
    def post(self):
        # 获取参数
        args, err = getArgsData()
        if err != None:
            return make_response(jsonify({'msg': err, }), 202)
        args['create_user'] = g.user_id
        args['type'] = 2
        args['id'] = caseGetPrimaryKeyData()
        args['lessees_id'] = g.lessees_id
        # 序列化跟校验参数
        addData, err = serializeParData(model=usersViewModel, argsData=args)
        if err != None:
            return make_response(jsonify({'msg': err}), 202)
        addData['password'] = base64Jia(addData['password'])
        # 判断编码是否重复
        exit_z = db.session.query(usersViewModel).filter_by(code=args['code'],lessees_id=g.lessees_id).first()
        if exit_z != None:
            return make_response(jsonify({'msg': '编码重复'}), 202)
        # 判断名称是否重复
        exit_z = db.session.query(usersViewModel).filter_by(username=args['username'],lessees_id=g.lessees_id).first()
        if exit_z != None:
            return make_response(jsonify({'msg': '名称重复'}), 202)
        result = db.session.query(usersViewModel).with_for_update().filter_by(id=args['id']).first()
        # 如果数据不存在，则添加新数据
        if result != None:
            db.session.commit()
            return make_response(jsonify({'msg': '抢先操作重新提交试试'}), 202)
        try:
            add = usersViewModel(**addData)
            db.session.add(add)
            db.session.commit()
            db.session.flush()
            objData = model_to_dict(add, [])
        except Exception as e:
            return make_response(jsonify({'msg': '新增失败' + repr(e)}), 202)

        return make_response(jsonify({'msg': '成功', 'result': objData}), 200)

class loginPkView(Resource):
    # 获取单个用户
    @login_required()
    def get(self, pk):
        filterList = []
        filterList.append(usersViewModel.id==pk)
        if g.lessees_type!=1:
            filterList.append(usersViewModel.lessees_id==g.lessees_type)
        user = usersViewModel.query.filter(*filterList).first()
        if user is None:
            return make_response(jsonify({'msg': '用户不存在'}), 400)
        userData = model_to_dict(user, [])

        try:
            userData['password'] = base64Jie(userData['password'])
        except Exception as e:
            return make_response(jsonify({'msg': '存储密码解密异常' + repr(e)}), 202)

        return make_response(jsonify({'msg': 'ok', 'result': userData}), 200)
    # 修改用户
    @login_required()
    def put(self, pk):
        args, err = getArgsData()
        if err != None:
            return make_response(jsonify({'msg': err, }), 202)
        # 判断名称是否重复
        if "code" in args.keys():
            del args['code']
        addData, err = serializeParData(model=usersViewModel, argsData=args)
        if err != None:
            return make_response(jsonify({'msg': err, }), 202)

        filterList = []
        if g.lessees_type != 1:
            filterList.append(usersViewModel.lessees_id == g.lessees_type)
        exit_z = db.session.query(usersViewModel).filter(*filterList,usersViewModel.id != pk,usersViewModel.username == args['username']).first()
        if exit_z != None:
            return make_response(jsonify({'msg': '名称重复', }), 202)
        addr = usersViewModel.query.filter(usersViewModel.id == pk,*filterList).with_for_update().first()
        for itm in addData.keys():
            setattr(addr, itm, addData[itm])
        db.session.commit()
        # 获取更新的数据
        update = usersViewModel.query.filter(*filterList,usersViewModel.id == pk).first()
        if update is None:
            return None, '获取更新后的数据失败'
        objData = model_to_dict(update, [])
        return make_response(jsonify({'msg': '成功', 'result': objData}), 200)

    # 删除用户
    @login_required()
    def delete(self, pk):
        # 查询数据
        result = usersViewModel.query.filter(usersViewModel.id == pk).first()
        if result == None:
            return make_response(jsonify({'msg': '数据不存在'}), 200)
        # 获取影藏不需要显示的数据
        resultData = model_to_dict(result, [])
        try:
            deletedata = db.session.query(usersViewModel).filter(usersViewModel.id == pk).with_for_update().first()
            deletedata.end_time = getDataTime(strftime='%Y-%m-%d 00:00:00')
            db.session.commit()
        except Exception as e:
            return make_response(jsonify({'msg': '删除失败' + repr(e)}), 200)

        return make_response(jsonify({'msg': '成功', 'result': resultData}), 200)

class loginView(Resource):
    # 用户登录
    def post(self):
        args = request.get_json()
        if args is None:
            return make_response(jsonify({'msg': '参数不能为空'}), 400)

        username = args.get('username', None)
        off = args.get('off', '')

        if username is None or username == '':
            return make_response(jsonify({'msg': '用户名称不能为空'}), 400)
        lessees_id = args.get('lessees_id', None)
        if lessees_id is None or lessees_id == '':
            return make_response(jsonify({'msg': '账套不能为空'}), 400)
        password = args.get('password', None)
        if password is None or password == '':
            return make_response(jsonify({'msg': '密码不能为空'}), 400)

        # 查询用户是否存在
        fliedList = [
            usersViewModel.id,
            usersViewModel.code,
            usersViewModel.username,
            usersViewModel.type,
            usersViewModel.start_time,
            usersViewModel.end_time,
            usersViewModel.dep_id,
            usersViewModel.create_time,
            usersViewModel.update_time,
            usersViewModel.lessees_id,
            usersViewModel.password,
            lesseesViewModel.name.label('lessees_name'),
            lesseesViewModel.type.label('lessees_type'),
            lesseesViewModel.start_time.label('lessees_start_time'),
            lesseesViewModel.end_time.label('lessees_end_time'),
            lesseesViewModel.online_num.label('online_num')
        ]
        existData = db.session.query(*fliedList).filter(usersViewModel.username==username,usersViewModel.lessees_id==lesseesViewModel.id,usersViewModel.lessees_id==lessees_id).first()
        if existData is None:
            return make_response(jsonify({'msg': '用户不存在'}), 400)
        # 校验密码是否相等
        if existData.password != base64Jia(password):
            return make_response(jsonify({'msg': '密码错误'}), 400)
        # 序列化用户信息
        userData = model_to_dict(existData, ['password'])
        # 判断账套是否过期
        verify_l = verifyDateOverdue(userData['lessees_end_time'])
        if verify_l == True:
            return make_response(jsonify({'msg': '系统过期请联系管理员'}), 400)
        # 判断账号是否过期
        verify_u = verifyDateOverdue(userData['end_time'])
        if verify_u == True:
            return make_response(jsonify({'msg': '账号过期请联系管理员'}), 400)

        # 判断登录用户数是否超出
        online_num = onLineViewModel.countLesseesData(userData['lessees_id'])
        if online_num > userData['online_num']:
            return make_response(jsonify({'msg': '在线用户'+ str(online_num) +'超出' }), 400)
        if off !=1:
            # 判断是否重复登录
            onLine = db.session.query(onLineViewModel).filter(
                onLineViewModel.lessees_id == userData['lessees_id'],
                onLineViewModel.user_id == userData['id']).first()
            if onLine!=None:
                return make_response(jsonify({'msg': '用户在线中请勿重新登录'}), 203)
        identity = {}
        identity['user_id'] = userData['id']
        identity['username'] = userData['username']
        identity['lessees_id'] = userData['lessees_id']
        identity['code'] = userData['code']
        identity['user_type'] = userData['type']
        identity['lessees_id'] = userData['lessees_id']
        identity['lessees_type'] = userData['lessees_type']
        identity['lessees_name'] = userData['lessees_name']
        identity['end_time'] = userData['end_time']
        identity['lessees_end_time'] = userData['lessees_end_time']
        # 查询用户权限
        permissionData = userPermission(userData['id'],userData['lessees_id'],userData['type'],userData['lessees_type'])
        userData['permission'] = permissionData
        # print(permissionData)
        # 生成token
        token = create_access_token(identity=identity)
        return make_response(jsonify({'msg': 'ok', 'token': token, 'data': userData}), 200)

    # 修改密码
    @login_required()
    def put(self):
        args = request.get_json()
        if args is None:
            return make_response(jsonify({'msg': '参数不能为空'}), 400)
        oldPassword = args.get('oldPassword',None)
        noewPassword = args.get('noewPassword',None)
        if oldPassword is None or oldPassword == '':
            return make_response(jsonify({'msg': '旧密码不能为空'}), 400)
        if noewPassword is None or noewPassword == '':
            return make_response(jsonify({'msg': '新密码不能为空'}), 400)
        # 获取token信息
        identity = get_jwt_identity()
        user_id = identity['user_id']
        existData = usersViewModel.query.filter_by(lessees_id=g.lessees_id,id=user_id).first()
        if existData is None:
            return make_response(jsonify({'msg': '用户不存在，被删除请重新登录试试'}), 400)
        if oldPassword != base64Jie(existData.password):
            return make_response(jsonify({'msg': '旧密码不一致请重新输入'}), 400)
        # 判断用户是否存在
        update_z = usersViewModel.query.filter_by(lessees_id=g.lessees_id,id=user_id).with_for_update().first()
        update_z.password = base64Jia(noewPassword)
        db.session.commit()
        return make_response(jsonify({'msg': 'ok'}), 200)

class refreshView(Resource):
    # 刷新token
    @login_required()
    def post(self):
        # 刷新token
        identity = get_jwt_identity()
        access_token = create_access_token(identity=identity)
        return make_response(jsonify({'msg': 'ok', 'token': access_token}), 200)
class logOutView(Resource):
    @login_required()
    def get(self):
        argsData = getParmData(None)
        argsData = getLessees(argsData)
        objData = getListOnLineModel(onLineViewModel, argsData)
        return make_response(jsonify({'msg': '成功', 'result': objData}), 200)

    @login_required()
    def post(self):
        """
        用户强制下线
        :return:
        """
        args = request.get_json()
        id_z = args.get('id',None)
        argsData = {}
        # 当为经销商用户可以轻质下线其他租户的账号,所有可以不用加租户
        if g.lessees_type == 1:
            if id_z !=None and id_z!='':
                argsData['id'] = id_z
            else:
                argsData['id'] = g.online_id
            # 推送消息
            print('推送 消息',argsData)
            clientLoginOut(argsData['id'])
        # 管理员可以强制下线其他用户所有可以通过参数传递需要下线的用户在线id
        elif g.user_type==1:
            argsData['lessees_id'] = g.lessees_id
            if id_z != None and id_z != '':
                argsData['id'] = id_z
            else:
                argsData['id'] = g.online_id
            # 推送消息
            clientLoginOut(argsData['id'])
        # 普通用户只能下线自己登录账号
        else:
            argsData['lessees_id'] = g.lessees_id
            argsData['id'] = g.online_id
        print('退出登录')
        _,err = onLineViewModel.deletePkData(argsData)
        if err!=None:
            return make_response(jsonify({'msg': err}), 202)
        return make_response(jsonify({'msg': 'ok'}), 200)

    @login_required()
    def put(self):
        """
        用户下线
        :return:
        """
        argsData = {}
        argsData['lessees_id'] = g.lessees_id
        argsData['id'] = g.online_id
        print('退出登录')
        _, err = onLineViewModel.deletePkData(argsData)
        if err != None:
            return make_response(jsonify({'msg': err}), 202)
        return make_response(jsonify({'msg': 'ok'}), 200)
    def delete(self):
        # 用户退出登录
        pass



